/*
 * @Author: soso
 * @Date: 2022-01-05 18:55:23
 * @LastEditTime: 2022-03-14 16:20:01
 * @LastEditors: Please set LastEditors
 * @Description: 主程序
 * @FilePath: /file-sync/main.go
 */
package main

import (
	"context"
	"fmt"
	"gomeshsync/config"
	"gomeshsync/core/cfiles"
	"log"
	"net"
	"os/signal"
	"syscall"
	"time"
)

// TODO: 考虑在一个全新节点上线时, 克隆一个节点的当时状态
func main() {
	conf := config.GetConfig()

	// 注册系统事件
	ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
	defer stop()

	defer config.WatchConfs(ctx).Close()

	// 创建监听服务
	listener, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", conf.DataPort))
	if err != nil {
		log.Println("Net.Listen err:", err)
		return
	}

	//监听端口
	go cfiles.SetListenService(listener, ctx)

	// 自动探测活跃节点
	if conf.AutoNodes {
		go cfiles.Pingpong(ctx)
	}

	// 开启文件块下载线程, 监测通道，传输数据块
	fb := cfiles.NewFileBlock()
	for i := 0; i < conf.Threads; i++ {
		go fb.DownloadBlock(ctx)
	}

	// 命令发现协程
	cfiles.StartFinder(ctx)

	//处理命令序列
	go cfiles.ProcessTemporaryCommands(ctx)

	//归档命令日志
	go cfiles.ArchiveCmds(ctx)

	// just for test
	// go func() {
	// 	for {
	// 		log.Println(pingpong.NewPingpong().GetNodes())
	// 		time.Sleep(time.Second * 3)
	// 	}
	// }()

	everLoop(ctx, listener) // 无限循环
	log.Println("graceful shutdown")
}

// 无限循环
func everLoop(ctx context.Context, listener net.Listener) {
LOOP:
	for {
		select {
		case <-ctx.Done():
			// 收到信号退出无限循环
			listener.Close()
			cfiles.NewFileBlock().ReleaseChans()
			break LOOP
		default:
			time.Sleep(time.Second)
		}
	}
}
